Unit PostBox;
Interface
Uses Routine, List, Process,Buffer, DispProc;
	type 
		PPostBox = ^TPostBox;
		TPostBox = object
			private
				listMessagePointer:	TList;
				listSendProc:		TList;
				listWaitProc:		TList;
			public
				Constructor Init;
				Destructor done;
				Procedure PutMessage(m:pointer);
				Function GetMessage:pointer;
		end;
Implementation
	
	(* TPostBox *)
	
	
	(* Constructor *)
	Constructor TPostBox.Init;
		begin
			listMessagePointer.init(sizeof(pointer));
			listSendProc.init(sizeof(TProcess));
			listWaitProc.init(sizeof(TProcess));
		end;
	
	(* Destructor *)
	Destructor TPostBox.done;
		var
			p:pointer;
		begin
			while (not listMessagePointer.empty) do
				begin
					if (listMessagePointer.front(p)) then
						begin
							freeMem(p, sizeof(buf_message));
							listMessagePointer.pop_front;
						end;
				end;
			listSendProc.done;
			listWaitProc.done;
		end;
		
	(* PutMessage *)
	Procedure TPostBox.PutMessage;
		var
			cur:TProcess;
			wait:TProcess;
		begin
			disable_interrupt;
			listMessagePointer.push_back(m);
			if (not listWaitProc.empty) then
				begin
					if (listWaitProc.front(wait)) then
						begin
							get_current_dispatcher^.get_current_process(cur);
							listWaitProc.pop_front;
							listSendProc.push_back(cur);
							get_current_dispatcher^.resumeProcessNow(wait);
							get_current_dispatcher^.delayProcess(cur);
							enable_interrupt;
							get_current_dispatcher^.activate_next_process;
						end;
				end
			else
				begin
					get_current_dispatcher^.get_current_process(cur);
					listSendProc.push_back(cur);
					get_current_dispatcher^.delayProcess(cur);
					enable_interrupt;
					get_current_dispatcher^.activate_next_process;
					
				end;
		end;
		
		Function TPostBox.GetMessage;
		var
			cur:	TProcess;
			send:	TProcess;
			M:pointer;
		begin
			disable_interrupt;
			{если в очереди сообщений нет сообщений, блокируем текущий процесс}
			if (listMessagePointer.empty) then
				begin
					get_current_dispatcher^.get_current_process(cur);
					listWaitProc.push_back(cur);
					get_current_dispatcher^.delayProcess(cur);
					enable_interrupt;
					get_current_dispatcher^.activate_next_process;
					disable_interrupt;
				end;
			if (listMessagePointer.front(M)) then
				begin
					listMessagePointer.pop_front;
					GetMessage:=M;
					if (listSendProc.front(send)) then
						begin
							listSendProc.pop_front;
							get_current_dispatcher^.resumeProcessNow(send);
							enable_interrupt;
							get_current_dispatcher^.activate_next_process;
						end;
				end;

		end;
begin
	
end.